/*
* 剪枝方法
* 1.优化搜索顺序：从大到小枚举
* 2.排除等效冗余：(1)按照组合数枚举 
                 (2)如果当前木棍dfs失败 && 下一根木棍和当前木棍长度相同，下一根木棍可以直接跳过
                 (3)如果是木棒的第一根木棍直接失败，则之前的方案一定失败（枚举当前木棒的合法解需要组合之前木棒的木棍
                 (4)放到最后一个失败，则之前方案一定失败，参考(3), 木棍交换不影响正确性
* 3.可行性剪枝:不符合规则，直接剪枝
* 4.最优化剪枝：不是最优解，直接剪枝
* 5.记忆化搜索：DP
*/
#include <iostream>
#include <algorithm>
using namespace std;

inline int read() {
    int x = 0; bool f = 1; char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    if (f) return x;
    return 0 - x;
}

bool cmp(int a, int b) { return a > b; }
int n, m, a[66], nxt[66], cnt, sum, len;
bool used[66], ok; // 访问数组，记录每根木棍是否用过

void dfs(int k, int last, int rest) // k正在拼第几根<=m last正在拼的前一节编号 rest还剩多长》=0
{
    int i;
    if (!rest) { // 如果当前已经拼完
        if (k == m) { ok = 1; return; } // 如果已经拼完m根，则直接返回

        for (i = 1; i <= cnt; i++) // 找一个还没用过的，最终每根木棍都要用上
            if (!used[i]) break;
        used[i] = 1;
        dfs(k + 1, i, len-a[i]);
        used[i] = 0; // 恢复现场
        if (ok) return;
    }

    // 二分查找第一个小于等于当前剩下长度的木棍
    int l = last + 1, r = cnt, mid;
    while (l < r)
    {
        mid = (l + r) >> 1;
        if (a[mid] <= rest) r = mid;
        else l = mid + 1;
    }

    for (i = l; i <= cnt; i++)
    {
        if(!used[i]){ // 当前这一根是否用过
            used[i] = 1;
            dfs(k, i, rest - a[i]);
            used[i] = 0;
            if (ok)  return; // 如果全部结束就直接返回

            if (rest == a[i] || rest == len) return; // 如果当前剩下的正好是当前这根木棍的长度或者是原长就直接返回
            //1.当前这根最优情况(正好拼成一根)都不行说明前面有问题
            //2.剩下的木棍拼不出来剩下的原根数说明前面也有问题
            i = nxt[i]; // 直接跳到下一根
            if (i == cnt) return; // 遍历到最后一根直接返回
        }
    }
}

int main()
{
    // 0.输入数据

    n = read();
    int d;
    for (int i = 1; i <= n; i++)
    {
        d = read();
        if (d > 50) continue;
        a[++cnt] = d;
        sum += d;
    }

    // 1.从大到小排序
    sort(a + 1, a + cnt + 1, cmp);

    // 2.预处理nxt数组(比当前长的木棍的下标)
    nxt[cnt] = cnt;
    for (int i = cnt - 1; i > 0; i--) {
        if (a[i] == a[i + 1]) nxt[i] = nxt[i + 1];
        else nxt[i] = i;
    }

    // 3.枚举原始长度
    for (len = a[1]; len <= sum / 2; len++) {
        if (sum % len) continue; // 如果不能拼出整数根，则剪枝
        m = sum / len; // 拼的个数
        ok = 0;
        used[1] = 1;
        dfs(1, 1, len - a[1]);
        used[1] = 0;
        if (ok) {
            printf("%d\n", len);
            return 0;
        }
        
    }
        printf("%d\n", sum);

}